"""
目标链接: https://555dycom.com/
编写爬虫代码时间: 2024-5-10
结束时间: 无
编写人: yy
"""
import re
import requests
from lxml import etree


# 定义爬虫类, 此类作为爬虫全部核心代码
class Script:
    def __init__(self):
        """
        初始化基础内容: 目标域名、请求头
        """
        self._domain = 'https://555dycom.com'
        self._headres = {
            "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
        }

    # 内部函数, 用来简化代码
    def _yy_request_return_text(self, **kwargs):
        # 获取网页内容并转成utf8返回
        html_str = requests.get(url=kwargs.get('url'), headers=kwargs.get('headres'))
        html_str.encoding = 'utf-8'
        return html_str.text

    def _yy_return_etree(self, html_str):
        # 返回 etree.HTML 对象
        return etree.HTML(html_str)

    def _yy_return_movie_v1(self, lis):
        """
        返回: 封面图、链接、名称、分辨率或集数
        """
        MovieList = []
        for obj in lis:
            MovieList.append({
                "images": obj.xpath('./div/a/@data-original')[0],
                "link": self._domain + obj.xpath('./div/a/@href')[0],
                "name": obj.xpath('./div/a/@title')[0],
                "SD": obj.xpath('./div/a/span[@class="pic-text text-right"]/text()')[0]
            })
        return MovieList

    # 返回搜索类的数据
    def _yy_return_search_data(self, lis):
        movies = []
        for obj in lis:
            movies.append({
                "name": obj.xpath('./div/a/@title')[0],
                "images": obj.xpath('./div/a/@data-original')[0],
                "sd": obj.xpath('./div/a/span[2]/text()')[0],
                "lead": obj.xpath('./div[2]/p[1]/text()')[0],
                "director": obj.xpath('./div[2]/p[2]/text()')[0],
                "link": self._domain + obj.xpath('./div[2]/p[4]/a/@href')[0]
            })
        return movies

    # 获取影视类型的详细视频
    def _yy_return_movie_more_list(self, movie_url):
        result = {
            "list": "",
            "pages": ""
        }
        html_str = self._yy_return_etree(html_str=self._yy_request_return_text(**{
            "url": movie_url,
            "headres": self._headres
        }))
        response = self._yy_return_movie_v1(lis=html_str.xpath('/html/body/div[1]/div/div[3]/div/div[2]/ul/li'))
        pages = html_str.xpath('/html/body/div[1]/div/ul/li')
        if pages:
            result['pages'] = self._yy_return_feye_data(lis=pages)

        result['list'] = response
        return result

    # 获取分页数据
    def _yy_return_feye_data(self, lis):
        pages = []
        a = 0
        for obj in lis:
            className = obj.xpath('./@class')
            if className:
                if str(className[0]).count("active"):
                    if a == 1:
                        pages.append({
                            "name": obj.xpath('./span/text()')[0],
                            "link": "",
                            "this": "no",
                            "count_page": "yes"
                        })
                        continue
                    a = 1
                    pages.append({
                        "name": obj.xpath('./a/text()')[0],
                        "link": self._domain + obj.xpath('./a/@href')[0],
                        "this": "yes",
                        "count_page": "no"
                    })
                else:
                    pages.append({
                        "name": obj.xpath('./a/text()')[0],
                        "link": self._domain + obj.xpath('./a/@href')[0],
                        "this":"no",
                        "count_page": "no"
                    })

        return pages

    # 获取播放链接
    def _yy_return_movie_play_info(self, lis):
        play_list = []
        for obj in lis:
            play_list.append({
                "link": self._domain + obj.xpath('./a/@href')[0],
                "name": obj.xpath('./a/text()')[0],
            })
        return play_list

    # 获取m3u8
    def _yy_return_m3u8_link(self, html_str):
        search_response = str(re.findall(pattern=r'},"url":"(.*?)"', string=html_str)[0]).replace('\\', '')
        return search_response

    # 获取姓名、对应链接
    def _yy_return_movie_athor(self, lis):
        lead_list = []
        for obj in lis:
            lead_list.append({
                "name": obj.xpath('./text()')[0],
                "link": self._domain + obj.xpath('./@href')[0]
            })
        return lead_list

    # 获取首页信息: 最近更新、电影、电视剧、综艺、动漫
    def GetIndexMovieData(self):
        html_str = self._yy_return_etree(self._yy_request_return_text(**{
            "url": self._domain,
            "headres": self._headres
        }))
        MovieList = []
        for i in range(2, 7):
            if i == 2:
                Obj = self._yy_return_movie_v1(
                    lis=html_str.xpath(f'/html/body/div[1]/div/div[{i}]/div/div[2]/ul[1]/li'))

            else:
                Obj = self._yy_return_movie_v1(
                    lis=html_str.xpath(f'/html/body/div[1]/div/div[{i}]/div/div[2]/div[2]/ul[1]/li'))
            MovieList.append({"data": Obj})
        return MovieList

    # 获取影视的详情数据
    def GetMovieInfo(self, movie_url):
        html_str = self._yy_return_etree(html_str=self._yy_request_return_text(**{
            "url": movie_url,
            "headres": self._headres
        }))
        # 取封面和SD
        img_sd = {
            "images": html_str.xpath('/html/body/div[1]/div/div[1]/div[1]/div/div/div/div[1]/a/img/@data-original')[0],
            "sd": html_str.xpath('/html/body/div[1]/div/div[1]/div[1]/div/div/div/div[1]/a/span[2]/text()')[0]}
        # 取标题、评分、类型、地区、年份、语言、主演、导演、更新
        info_xpath = html_str.xpath('/html/body/div[1]/div/div[1]/div[1]/div/div/div/div[2]')[0]
        movie_info = {
            "name": info_xpath.xpath('./h1/text()')[0],
            "score": info_xpath.xpath('./div[1]/span/text()')[0],
            "lead": self._yy_return_movie_athor(lis=info_xpath.xpath('./p[2]/a')),
            "director": self._yy_return_movie_athor(lis=info_xpath.xpath('./p[3]/a')),
            "update": info_xpath.xpath('./p[4]/text()')[0],
        }
        # 取播放链接
        play_list = self._yy_return_movie_play_info(
            lis=html_str.xpath('/html/body/div[1]/div/div[1]/div[2]/div/div[2]/ul/li'))

        # 获取猜你喜欢
        GetGuessLink = self._yy_return_movie_v1(
            lis=html_str.xpath('/html/body/div[1]/div/div[1]/div[6]/div/div[2]/ul/li | /html/body/div[1]/div/div[1]/div[7]/div/div[2]/ul/li'))

        return {
            "img_sd": img_sd,
            "movie_info": movie_info,
            "play_list": play_list,
            "GetGuessLink": GetGuessLink
        }

    # 获取影视的播放信息、m3u8链接等
    def GetMoviePlayInfo(self, movie_url):
        # 获取m3u8播放链接
        html_str = self._yy_request_return_text(**{
            "url": movie_url,
            "headres": self._headres
        })
        etree_str = self._yy_return_etree(html_str)
        movie_info_xpath = etree_str.xpath('/html/body/div[1]/div/div[1]/div[1]/div/div/div/div[2]')[0]
        # 获取猜你喜欢
        GetGuessLink = self._yy_return_movie_v1(
            lis=etree_str.xpath('/html/body/div[1]/div/div[1]/div[7]/div/div[2]/ul/li | /html/body/div[1]/div/div[1]/div[8]/div/div[2]/ul/li'))
        movie_info = {
            "m3u8_link": self._yy_return_m3u8_link(html_str=html_str),
            "name": movie_info_xpath.xpath('./h1/text()')[0],
            "play_list": self._yy_return_movie_play_info(
                lis=etree_str.xpath('/html/body/div[1]/div/div[1]/div[3]/div/div[2]/ul/li')),
            "plot": etree_str.xpath('/html/body/div[1]/div/div[1]/div[6]/div/div[2]/div/span[2]/text() | /html/body/div[1]/div/div[1]/div[7]/div/div[2]/div/span[2]/text()'),
            "GetGuessLink": GetGuessLink
        }
        return movie_info

    # 根据分页获取数据, 请注意参数
    def GetMovieMore(self, movie_type: int, page=1):
        """
        movie_type(可选) = [0电影、1电视剧、2综艺、3动漫]
        """

        movie_type_db = ["dianying", "dianshiju", "zongyi", "dongman"]
        if movie_type is not None:
            return self._yy_return_movie_more_list(
                    movie_url=f'https://555dycom.com/livodtype/{movie_type_db[movie_type]}-{page}.html')
        else:
            return ''

    # 搜索影视：根据片名搜索、根据人物名字搜索
    def SesrchMovie(self, wd, movie_type=1):
        """
        movie_type: [1影视搜索、2主演名称搜索、3类型搜索、4时间搜索、5导演搜索、6语言搜索]
        """
        url = 'https://555dycom.com/livodsearch/'
        if movie_type == 1:
            url = url + f'-------------.html?wd={wd}&submit='
        elif movie_type == 2:
            url = url + f'-{wd}------------.html'
        elif movie_type == 3:
            url = url + f'----{wd}---------.html'
        elif movie_type == 4:
            url = url + f'-------------{wd}.html'
        elif movie_type == 5:
            url = url + f'-----{wd}--------.html'
        elif movie_type == 6:
            url = url + f'------{wd}-------.html'
        else:
            return ""
        movie_info = {"list":"", "pages": ""}
        html_str = self._yy_return_etree(self._yy_request_return_text(**{
            "url": url,
            "headres": self._headres
        }))
        movies = self._yy_return_search_data(lis=html_str.xpath('/html/body/div[1]/div/div[1]/div/div/div[2]/ul/li'))
        movie_info['list'] = movies
        pages = html_str.xpath('/html/body/div[1]/div/div[1]/ul/li')
        if pages:
            movie_info['pages'] = self._yy_return_feye_data(lis=pages)
        return movie_info


if __name__ == '__main__':
    sp = Script()

    print(sp.GetMovieInfo(movie_url="https://555dycom.com/livoddetail/77396.html"))
